package com.eagleframework.component.beans;

import com.eagle.util.annotation.AnnotationUtil;
import com.eagle.util.text.StringUtil;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;

/**
 * Bean替换机制的具体实现
 *
 * <p>带有{@code @BeanReplace}注解的Bean在创建时会在Spring容器中查询指定名称的Bean，如果存在则删除
 *
 * @author yaoxing
 * @see com.eagleframework.component.beans.BeanReplace
 * @since 0.0.1
 */
public class EagleReplaceBeanPostProcessor implements BeanPostProcessor {
    @Autowired
    private DefaultListableBeanFactory defaultListableBeanFactory;
    
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        Class<?> beanClass = bean.getClass();
        BeanReplace newBean = AnnotationUtil.getAnnotation(beanClass, BeanReplace.class);
        if (newBean != null && defaultListableBeanFactory.containsBean(beanName)) {
            String name = newBean.value();
            if (StringUtil.isBlank(name)) {
                Class<?> superclass = beanClass.getSuperclass();
                name = StringUtil.lowerFirst(superclass.getSimpleName());
            }
            if (defaultListableBeanFactory.containsBean(name)) {
                BeanReplace oldBean = defaultListableBeanFactory.findAnnotationOnBean(name, BeanReplace.class);
                if (oldBean == null) {
                    defaultListableBeanFactory.removeBeanDefinition(name);
                } else {
                    int newBeanOrder = newBean.order();
                    int oldBeanOrder = oldBean.order();
                    if (oldBeanOrder <= newBeanOrder) {
                        defaultListableBeanFactory.removeBeanDefinition(name);
                    }
                }
            }
        }
        return bean;
    }
}
